
package at.technikum_wien.embsys.aat.simpleapp;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Scanner;

import javax.swing.event.EventListenerList;

import at.technikum_wien.embsys.aat.PriscillaCore.data.EnoceanRawData;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.BinaryState;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.ErrorCode;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.EventSend;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.TeachInOptions;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEvent;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventBinary;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventError;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventFan;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventGetGatewayID;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventHumidity;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventIllumination;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventLearnTelegram;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventSetPoint;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventSupplyVoltage;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventTemperature;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventWindowHandle;
import at.technikum_wien.embsys.aat.PriscillaCore.link.EnOceanLinkImpl;
import at.technikum_wien.embsys.aat.PriscillaCore.link.event.LinkListener;
import at.technikum_wien.embsys.aat.PriscillaCore.link.event.RemoteEventListener;

public class SimpleAppIP {
	
	private static final int PortNumber = 5000;
	//private static final String ipAdress = "172.22.0.218";	// Homer PC
	//private static final String ipAdress = "127.0.0.1";		// loopback
	//private static final String ipAdress = "172.22.0.1";		// AAT-Server
	private static final String ipAdress = "172.22.0.27";		// IP Gateway
	
	static String gateway = "";

	static EventListenerList listenerList = new EventListenerList();

	public static void main(String[] args) throws IOException {

		InetSocketAddress remoteIP = new InetSocketAddress(ipAdress, PortNumber);
		final EnOceanLinkImpl netLink = new EnOceanLinkImpl(remoteIP, TeachInOptions.ONE_TIME);

		final Scanner input = new Scanner(System.in);

		@SuppressWarnings("unused")
		final SimpleAppIP simpleAppReceiver = new SimpleAppIP();

		netLink.addLinkListener(new LinkListener() {
			public void frameReceived_Binary(FrameEventBinary e) {
				System.out.println("Binary Event:         DeviceID: " + e.getDeviceID() + ",         DeviceA: " + e.getDeviceA() + ", DeviceB: "
						+ e.getDeviceB() + ", DeviceC: " + e.getDeviceC() + ", DeviceD: " + e.getDeviceD());
			}

			public void frameReceived_Temperature(FrameEventTemperature e) {
				System.out.println("Temperature Event:    DeviceID: " + e.getDeviceID() + ",         Temperature: " + e.getTemperatureValue());
			}

			public void frameReceived_Humidity(FrameEventHumidity e) {
				System.out.println("Humidity Event:    DeviceID: " + e.getDeviceID() + ",            Humidity: " + e.getHumidityValue());
			}

			public void frameReceived_Illumination(FrameEventIllumination e) {
				System.out.println("Illumination Event:     DeviceID: " + e.getDeviceID() + ",        Illumination: " + e.getIlluminationValue());
			}

			public void frameReceived_SupplyVoltage(FrameEventSupplyVoltage e) {
				System.out.println("SupplyVoltage Event:    DeviceID: " + e.getDeviceID() + ",        SupplyVoltage: " + e.getSupplyVoltageValue());
			}

			public void frameReceived_SetPoint(FrameEventSetPoint e) {
				System.out.println("SetPoint Event:       DeviceID: " + e.getDeviceID() + ",         SetPoint: " + e.getSetPointValue());
			}

			public void frameReceived_Fan(FrameEventFan e) {
				System.out.println("Fan Event:            DeviceID: " + e.getDeviceID() + ",         FanState: " + e.getFanState() + ", FanType: "
						+ e.getFanType());
			}

			public void frameReceived_Gas(FrameEvent e) {

			}

			public void frameReceived_Time(FrameEvent e) {

			}

			public void frameReceived_WeatherStation(FrameEvent e) {

			}

			public void frameReceived_GatewayID(FrameEventGetGatewayID e) {
				System.out.println("Gateway device ID: " + e.getGatewayID());
				gateway = e.getGatewayID();
			}

			public void frameReceived_LearnTelegram(FrameEventLearnTelegram e) {
				System.out.println("LEARN BUTTON PRESSED  DeviceID: " + e.getDeviceID() + ", Func: " + e.getFunc() + ", Typ: " + e.getType());
			}

			public void frameReceived_Error(FrameEventError e) {
//				int func;
//				int type;
				System.out.println("Error Message received!         DeviceID: " + e.getDeviceID() + ",            ErrorMsg: " + e.getErrorMsg());
				if (e.getErrorCode() == ErrorCode.TEACHING_ERROR_UNABLE_TO_LEARN) {
					System.out.println("Please provide the TYPE for device " + e.getDeviceID() + ":");
					// while (!input.hasNextInt(16))
					// ;
					// type = input.nextInt(16);
					// System.out.println("Selected Type:" +
					// String.valueOf(type));

					System.out.println("Please provide the FUNC for device " + e.getDeviceID() + ":");
					// while (!input.hasNextInt(16))
					// ;
					// func = input.nextInt(16);
					// System.out.println("Selected Func:" +
					// String.valueOf(func));

					// netLink.addDeviceManually(func, type, e.getDeviceID());
				}
			}

			public void frameReceived(FrameEvent e) {
				EnoceanRawData enoceanRawData = e.getEnoceanDataFrame();
				System.out.println(enoceanRawData.getString());
			}

			public void frameReceived_RainSensor(FrameEvent e) {
			}

			public void frameReceived_DayNight(FrameEvent e) {
			}

			public void frameReceived_WindowHandle(FrameEventWindowHandle e) {
				// TODO Auto-generated method stub
				
			}
		});

		for (;;) {
			// ----------------------------------------------------------------------------
			// Simple Keyboard Demo Programm
			// send Binary Events with ID 0 or ID 0x0F to the actuator
			if (input.hasNext()) {
				String temp;
				temp = input.nextLine();

				if (temp.equals("A0")) {
					netLink.sendEvent(EventSend.BINARY_EVENT, 0, BinaryState.FALSE, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN);
					netLink.sendEvent(EventSend.BINARY_EVENT, 0, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN);
				}
				if (temp.equals("A1")) {
					netLink.sendEvent(EventSend.BINARY_EVENT, 0, BinaryState.TRUE, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN);
					netLink.sendEvent(EventSend.BINARY_EVENT, 0, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN);
				}
				if (temp.equals("B0")) {
					netLink.sendEvent(EventSend.BINARY_EVENT, 0x0F, BinaryState.UNKNOWN, BinaryState.FALSE, BinaryState.UNKNOWN, BinaryState.UNKNOWN);
					netLink.sendEvent(EventSend.BINARY_EVENT, 0x0F, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN,
							BinaryState.UNKNOWN);
				}
				if (temp.equals("B1")) {
					netLink.sendEvent(EventSend.BINARY_EVENT, 0x0F, BinaryState.UNKNOWN, BinaryState.TRUE, BinaryState.UNKNOWN, BinaryState.UNKNOWN);
					netLink.sendEvent(EventSend.BINARY_EVENT, 0x0F, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN,
							BinaryState.UNKNOWN);
				}
				if (temp.equals("C0"))
					netLink.sendEvent(EventSend.BINARY_EVENT, gateway, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.FALSE,
							BinaryState.UNKNOWN);
				if (temp.equals("C1"))
					netLink.sendEvent(EventSend.BINARY_EVENT, gateway, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.TRUE,
							BinaryState.UNKNOWN);
				if (temp.equals("D0"))
					netLink.sendEvent(EventSend.BINARY_EVENT, gateway, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN,
							BinaryState.FALSE);
				if (temp.equals("D1"))
					netLink.sendEvent(EventSend.BINARY_EVENT, gateway, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN,
							BinaryState.TRUE);
			} // if (input.hasNext())
		} // for (;;)
	} // public static void main(String[] args)

	public void addRemoteListener(RemoteEventListener l) {
		listenerList.add(RemoteEventListener.class, l);
	}

	public void removeRemoteListener(RemoteEventListener l) {
		listenerList.remove(RemoteEventListener.class, l);
	}
}
